package com.itheima.advantagesup.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.itheima.advantagesup.common.BaseContext;
import com.itheima.advantagesup.common.constant.LoginConstant;
import com.itheima.advantagesup.dto.UserLoginDTO;
import com.itheima.advantagesup.entity.SysDict;
import com.itheima.advantagesup.entity.SysMenu;
import com.itheima.advantagesup.entity.SysUser;
import com.itheima.advantagesup.exception.BusinessException;
import com.itheima.advantagesup.mapper.SysDictMapper;
import com.itheima.advantagesup.mapper.SysMenuMapper;
import com.itheima.advantagesup.mapper.SysRoleMapper;
import com.itheima.advantagesup.mapper.SysUserMapper;
import com.itheima.advantagesup.service.IndexService;
import com.itheima.advantagesup.utils.IpUtils;
import com.itheima.advantagesup.utils.JwtUtil;
import com.itheima.advantagesup.vo.MenuVO;
import com.itheima.advantagesup.vo.ProfileVO;
import com.itheima.advantagesup.vo.UserInfoVO;
import com.itheima.advantagesup.vo.UserLoginVO;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * IndexServiceImpl
 *
 * @author liliudong
 * @version 1.0
 * @description
 * @date 2023/7/26 17:48
 */
@Service
@RequiredArgsConstructor
public class IndexServiceImpl implements IndexService {

    private final JwtUtil jwtUtil;
    private final IpUtils ipUtils;

    private final SysUserMapper sysUserMapper;

    private final SysRoleMapper sysRoleMapper;

    private final SysMenuMapper sysMenuMapper;

    private final SysDictMapper sysDictMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserLoginVO login(UserLoginDTO userLoginDTO) {
        SysUser sysUser = sysUserMapper.selectByUserName(userLoginDTO.getLogin_name());
        if (Objects.isNull(sysUser)) {
            throw new BusinessException("账号不正确");
        }
        String digest = DigestUtils.md5DigestAsHex(userLoginDTO.getPassword().getBytes());
        if (!Objects.equals(digest, sysUser.getPassword())) {
            throw new BusinessException("密码不正确");
        }
        sysUser.setLoginIp(ipUtils.getClientIp());
        sysUser.setLoginDate(LocalDateTime.now());
        sysUser.setUpdateDate(LocalDateTime.now());
        sysUserMapper.updateById(sysUser);

        HashMap<String, Object> map = new HashMap<>(8);
        map.put(LoginConstant.USER_ID, sysUser.getId());
        String jwt = jwtUtil.createJWT(map);
        return UserLoginVO.builder().token(jwt).build();
    }

    @Override
    public ProfileVO profile() {
        ProfileVO profileVO = new ProfileVO();
        UserInfoVO userInfoVO = getUserInfoVO();
        List<MenuVO> menuVOS = getMenuVOList(userInfoVO);
        Map<String, Object> dictListMap = getDictListMap();
        ArrayList<String> btnList = getBtnList();

        profileVO.setUserInfo(userInfoVO);
        profileVO.setMenuList(menuVOS);
        profileVO.setDictsList(dictListMap);
        profileVO.setBtnList(btnList);

        return profileVO;
    }

    /**
     * 获取菜单列表
     *
     * @return
     */
    private ArrayList<String> getBtnList() {
        ArrayList<String> btnList = new ArrayList<>();
        btnList.add("*");
        return btnList;
    }

    /**
     * 获取字典列表
     *
     * @return
     */
    private Map<String, Object> getDictListMap() {
        HashMap<String, Object> result = new HashMap<>(16);
        List<SysDict> sysDictList = sysDictMapper.selectList();
        sysDictList.forEach(sysDict -> {
            HashMap<String, Object> item = new HashMap<>(8);
            item.put(sysDict.getValue(), sysDict.getLabel());
            result.put(sysDict.getType(), item);
        });
        return result;
    }

    /**
     * 获取菜单列表
     *
     * @param userInfoVO
     * @return
     */
    private List<MenuVO> getMenuVOList(UserInfoVO userInfoVO) {
        List<SysMenu> sysMenus = sysMenuMapper.selectListByRoleIds(userInfoVO.getRole_id());

        return sysMenus.stream().map(sysMenu -> {
            MenuVO menuVO = new MenuVO();
            menuVO.setId(sysMenu.getId());
            menuVO.setPid(sysMenu.getPid());
            menuVO.setPath(sysMenu.getPath());
            menuVO.setComponent(sysMenu.getComponent());
            menuVO.setTitle(sysMenu.getTitle());
            menuVO.setIcon(sysMenu.getIcon());
            menuVO.setIs_show(sysMenu.getIsShow());
            menuVO.setIs_cache(sysMenu.getIsCache());
            menuVO.setIs_link(sysMenu.getIsLink());
            menuVO.setRedirect(sysMenu.getRedirect());
            menuVO.setCreateDate(sysMenu.getCreateDate());
            menuVO.setUpdateDate(sysMenu.getUpdateDate());
            menuVO.setDel_flag(sysMenu.getDelFlag());
            menuVO.setType(sysMenu.getType());
            menuVO.setSort(sysMenu.getSort());
            menuVO.setMark(sysMenu.getMark());
            return menuVO;
        }).collect(Collectors.toList());
    }

    /**
     * 获取用户详情信息
     *
     * @return
     */
    private UserInfoVO getUserInfoVO() {
        SysUser sysUser = sysUserMapper.selectById(BaseContext.getLoginUserId());
        String roleIdJsonArr = sysUser.getRoleId();

        UserInfoVO userInfoVO = new UserInfoVO();
        if (StringUtils.isNotBlank(roleIdJsonArr)) {
            JSONArray roleIds = JSON.parseArray(roleIdJsonArr);
            List<String> roleIdsJavaList = roleIds.toJavaList(String.class);
            userInfoVO.setRole_id(roleIdsJavaList);
            List<String> roleNameList = sysRoleMapper.selectNameListByIds(roleIdsJavaList);
            userInfoVO.setRolename(roleNameList);
        }
        userInfoVO.setId(sysUser.getId());
        userInfoVO.setLogin_name(sysUser.getLoginName());
        userInfoVO.setName(sysUser.getName());
        userInfoVO.setEmail(sysUser.getEmail());
        userInfoVO.setPhone(sysUser.getPhone());
        userInfoVO.setLogin_ip(sysUser.getLoginIp());
        userInfoVO.setLogin_date(sysUser.getLoginDate());
        userInfoVO.setCreate_date(sysUser.getCreateDate());
        userInfoVO.setUpdate_date(sysUser.getUpdateDate());
        userInfoVO.setDel_flag(sysUser.getDelFlag());
        userInfoVO.setStatus(sysUser.getStatus());
        return userInfoVO;
    }
}
